package org.infodavid.common.model.impl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.infodavid.common.model.impl.AbstractImprovedDataObjectImpl;
import org.infodavid.common.model.security.IAccessControlEntry;
import org.infodavid.common.model.security.ISecuredObjectIdentifier;

/**
 * The Class AccessControlListImpl.
 */
public class AccessControlEntryImpl extends AbstractImprovedDataObjectImpl<Long> implements
    IAccessControlEntry {

	/** serialVersionUID. */
	private static final long serialVersionUID = -1478066595640761601L;

	/** The permissions. */
	private Map<String,Boolean> permissions;

	/** The object identifier. */
	private ISecuredObjectIdentifier objectIdentifier;

	/**
	 * constructor.
	 * @throws Exception the exception
	 */
	protected AccessControlEntryImpl() throws Exception {
		super();
	}

	/**
	 * constructor.
	 * @param keyArg the key
	 * @throws Exception the exception
	 */
	protected AccessControlEntryImpl(final Long keyArg) throws Exception {
		super();

		setKey(keyArg);
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.impl.DataObjectImpl#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}

		if (obj == null) {
			return false;
		}

		if (!(obj instanceof IAccessControlEntry)) {
			return false;
		}

		final IAccessControlEntry other = (IAccessControlEntry)obj;

		if (getObjectIdentifier() == null) {
			if (other.getObjectIdentifier() != null) {
				return false;
			}
		}
		else if (!getObjectIdentifier().equals(other.getObjectIdentifier())) {
			return false;
		}

		return true;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.security.IAccessControlEntry#getObjectIdentifier()
	 */
	public ISecuredObjectIdentifier getObjectIdentifier() {
		return objectIdentifier;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.impl.DataObjectImpl#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;

		result =
		    prime * result + (getObjectIdentifier() == null ? 0 : getObjectIdentifier().hashCode());

		return result;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.IBasicDataObject#init()
	 */
	@Override
	public void init() throws Exception {
		super.init();

		objectIdentifier = null;
		permissions = new HashMap<String,Boolean>();

	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.infodavid.common.model.security.IAccessControlEntry#setObjectIdentifier(org.infodavid.common
	 * .model.security.ISecuredObjectIdentifier)
	 */
	public void setObjectIdentifier(final ISecuredObjectIdentifier value) {
		if (!equals(objectIdentifier, value)) {
			final Object old = objectIdentifier;
			objectIdentifier = value;
			markModified(OBJECT_IDENTIFIER, old, objectIdentifier);
		}
	}

	/*
	 * See super class or interface. (non-Javadoc)
	 * @see org.infodavid.common.impl.model.DataObjectImpl#toString(java.lang.StringBuffer)
	 */
	@Override
	protected StringBuffer toString(final StringBuffer builder) {
		super.toString(builder);

		builder.append("[objectIdentifier=");
		builder.append(objectIdentifier);
		builder.append(", permissions=");

		if (permissions == null) {
			builder.append("null");
		}
		else {
			builder.append(Arrays.toString(permissions.keySet().toArray()));
		}

		builder.append("]");

		return builder;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.security.IAccessControlEntry#getPermissions()
	 */
	public Map<String,Boolean> getPermissions() {
		return permissions;
	}

	/**
	 * Sets the permissions.
	 * @param values the permissions
	 */
	public void setPermissions(final Map<String,Boolean> values) {
		final Object old = permissions;
		permissions = values;
		markModified(PERMISSIONS, old, permissions);
	}
}
